import zTable from './table.vue'
import zPagination from './pagination.vue'
import zFormDialog from './formDialog.vue'
import zForm from './form.vue'
import _ from 'lodash'
import dayjs from 'dayjs'
export default {
  components: {
    zTable,
    zPagination,
    zForm,
    zFormDialog,
  },
  data() {
    return {
      api: null,
      apiList: null,
      apiSingle: null,
      apiCreate: null,
      apiEdit: null,
      apiDelete: null,
      postForList: false, //是否使用post获取列表
      initData: {}, //创建数据时的默认对象，可以用来设置默认值或者初始化一些属性
      tableProps: {
        border: true,
        hideOperations: false,
        // opsColWith: 140, //不定义默认80
        // showSelection: true, // 是否开启复选
        // expandable: true, //是否展开行
        // showIndexCol: false, //是否显示索引列
        // indexColWidth: 50, //索引列宽度
      },
      formProps: {
        dialogWidth: '70%',
        labelWidth: '140px',
        // title:null, //dialog title
      },
      query: {
        size: 10,
        page: 1,
      },
      pagination: {
        //分页组件配置 如不需分页，可以把pagination设置为null
        layout: 'prev, pager, next, jumper, ->, total, sizes',
      },
      pageLoading: false, //页面的loading状态
      tableLoading: false, //表格的loading状态
      editFormVisible: false, //编辑模态框的显示状态
      submitLoading: false, //保存按钮的loading状态
      exportLoading: false, //导出按钮的loading状态
      list: [], //列表数据
      data: {}, //单条数据
      total: 0,
      columns: [],
      fields: [],
    }
  },
  methods: {
    research() {
      this.query.page = 1
      this.list = []
      this.total = 0
      this.getList()
    },
    getList() {
      this.pageLoading = true
      let url = this.apiList || this.api + 'getlist'
      this.$request(url, this.formatQuery(this.query), this.postForList ? 'post' : 'get')
        .then(r => {
          this.list = this.formatList(r.list)
          this.total = r.total
        })
        .finally(() => {
          this.pageLoading = false
        })
    },
    formatList(list) {
      //依据实际需求处理
      let tmp = _.cloneDeep(list)
      return tmp.map(i => {
        return i
      })
    },
    formatAfterGet(data) {
      //依据实际需求处理
      let tmp = _.cloneDeep(data)
      return tmp
    },
    formatBeforeSave(data) {
      //依据实际需求处理
      let tmp = _.cloneDeep(data)
      return tmp
    },
    formatQuery(query) {
      let tmp = _.cloneDeep(query)
      if (tmp.queryString && tmp.queryString.daterange && tmp.queryString.daterange.length > 1) {
        tmp.queryString.start = tmp.queryString.daterange[0]
        tmp.queryString.end = tmp.queryString.daterange[1]
        delete tmp.queryString.daterange
      }
      if (tmp.daterange && tmp.daterange.length > 1) {
        tmp.start = tmp.daterange[0]
        tmp.end = tmp.daterange[1]
        delete tmp.daterange
      }
      return tmp
    },
    createItem() {
      this.data = _.cloneDeep(this.initData)
      this.editFormVisible = true
    },
    editItem(v) {
      this.pageLoading = true
      let url = this.apiSingle || this.api + 'getbyid'
      this.$request(url, {
        id: v.id,
      })
        .then(r => {
          this.data = this.formatAfterGet(r)
          this.editFormVisible = true
        })
        .finally(() => {
          this.pageLoading = false
        })
    },
    deleteItem(v) {
      this.$confirm('确定要删除这条记录？').then(() => {
        this.pageLoading = true
        let url = this.apiDelete || this.api + 'delete'
        this.$request(url + '/' + v.id, {}, 'post')
          .then(r => {
            this.$message.success('操作成功')
            this.getList()
          })
          .finally(() => {
            this.pageLoading = false
          })
      })
    },
    validataData(fields, data) {
      fields = fields ? fields : []
      for (var i = 0; i < fields.length; i++) {
        let field = fields[i]
        if (field.hidden) return true
        if (field.required) {
          let value = data[field.key]
          if (value === null || value === '' || value === undefined || (Array.isArray(value) && value.length === 0)) {
            this.$message.error(`${field.title} 不能为空`)
            return false
          }
        }
      }
      return true
    },
    submit() {
      let insertUrl = this.apiCreate || this.api + 'add'
      let updateUrl = this.apiEdit || this.api + 'update'
      let url = this.data.id ? updateUrl : insertUrl
      let data = this.formatBeforeSave(this.data)
      let check = this.validataData(this.fields, data)
      if (!check) return
      this.submitLoading = true
      this.$request(url, data, 'post')
        .then(r => {
          this.$message.success('操作成功')
          this.editFormVisible = false
          this.getList()
        })
        .finally(() => {
          this.submitLoading = false
        })
    },
    updateCell({ index, key, val, rowOldData, rowData }) {
      this.data = rowData
      let insertUrl = this.apiCreate || this.api + 'add'
      let updateUrl = this.apiEdit || this.api + 'update'
      let url = this.data.id ? updateUrl : insertUrl
      let data = this.formatBeforeSave(this.data)
      let check = this.validataData(this.fields, data)
      if (!check) {
        this.$set(this.list, index, rowOldData)
        return
      }
      this.pageLoading = true
      this.$request(url, data, 'post')
        .finally(() => {
          this.pageLoading = false
        })
        .then(r => {
          this.$message.success('操作成功')
          this.getList()
        })
        .catch(() => {
          this.$set(this.list, index, rowOldData)
        })
    },
    exportData() {
      let url = this.apiList || this.api + 'getlist'
      let query = this.formatQuery(this.query)
      query.page = 1
      query.size = 99999
      this.exportLoading = true
      this.$request(url, query, this.postForList ? 'post' : 'get')
        .then(r => {
          var exprotList = this.formatList(r.list)
          import('@/vendor/Export2Excel').then(excel => {
            const filterVal = this.columns.map(item => {
              return item.key
            })
            const tHeader = this.columns.map(item => {
              return item.title || item.key
            })
            const data = exprotList.map(v => filterVal.map(j => v[j]))
            excel.export_json_to_excel({
              header: tHeader,
              data,
              filename: this.name + '_' + dayjs().format('YYYYMMDD'),
            })
          })
        })
        .finally(() => {
          this.exportLoading = false
        })
    },
    getFieldConfig(fieldName) {
      var j = _.findIndex(this.fields, i => i.key == fieldName)
      if (j != -1) {
        return this.fields[j]
      }
      return null
    },
    arrayOptions(arr, v, l, text) {
      let r = []
      // 有text 并且text为数组
      if (text && !Array.isArray(text)) {
        console.error('text参数必须为数组且顺序和label参数一致')
        return false
      }
      if (!text) {
        text = []
      }
      arr.forEach(item => {
        let data = ''
        if (!l) {
          data = item[v]
        } else if (Array.isArray(l)) {
          l.forEach((vtmp, index) => {
            data = data + ' ' + (text[index] ? text[index] : '') + item[vtmp]
          })
        } else {
          data = item[l]
        }
        if (item[v]) r.push({ value: item[v], label: data })
      })
      return r
    },

    setFieldOptions(fieldName, arr, v, l, text) {
      let tmp = []
      if (arr && arr.length > 0) {
        tmp = this.arrayOptions(arr, v, l, text)
      }
      var conf = this.getFieldConfig(fieldName)
      if (conf) {
        conf.options = tmp
      }
    },
    getArrayLabelByValue(arr, value, v, l) {
      arr = arr || []
      if (value === undefined || value === null) return null
      let tmp = arr.find(i => i[v] == value)
      if (tmp == null) return null
      return tmp[l]
    },
    /*
     * 设置字段的disable,fields可以是数组也可是字符串表示哪些字段需要disable.
     * disable是表示禁用还是启用会转换成布尔值
     * */
    setFieldsDisable(disable, fields, arr) {
      let newArr = arr || this.fields // 指定fields
      disable = Boolean(disable)
      newArr.forEach(item => {
        if (fields) {
          if (Array.isArray(fields)) {
            if (_.indexOf(fields, item['key']) < 0) {
              return true
            }
          } else {
            if (item.key != fields) {
              return true
            }
          }
        }
        if (!item.props || Object.prototype.toString.call(item.props) != '[object Object]') {
          item.props = { disabled: disable }
        } else {
          item.props['disabled'] = disable
        }
      })
    },
  },
}
